package ca.etsmtl.log730.lab3.controllers2;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Communicator extends Thread {
	private final Socket client;
	public Communicator(Socket clientSocket) {
		this.client = clientSocket;
		
	}
	
	public Communicator.OutputHandler createOutputHandler() throws IOException {
		return new OutputHandler(new ObjectOutputStream(client.getOutputStream()));
	}
	public Communicator.InputHandler createInputHandler() throws IOException {
		return new InputHandler(new ObjectInputStream(client.getInputStream()));
	}
	
	public static interface ObjectReaderHandler {
		public void handle(Object o);
	}
	
	public static class InputHandler extends Thread {
		private ObjectInputStream ois;
		private LinkedList<Object> inputQueue = new LinkedList<Object>();
		public List<ObjectReaderHandler> listeners = new ArrayList<ObjectReaderHandler>();
		
		public InputHandler(ObjectInputStream ois) {
			this.ois = ois;
		}
		public void addListener(ObjectReaderHandler orh) {
			listeners.add(orh);
		}
		public void removeListener(ObjectReaderHandler orh) {
			listeners.remove(orh);
		}
		public void run() {
			while(true) {
				try {
					Object o = ois.readObject();
					System.out.println("READ: " + o.toString());
					inputQueue.addFirst(o);
				} catch (IOException e) {
					e.printStackTrace();
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
				
				Thread.yield();
			}
		}
		
		public Object readLast() {
			Object o = inputQueue.pop();
			
			return o;
		}
	}
	public static class OutputHandler extends Thread {
		private ObjectOutputStream oos;
		private LinkedList<Object> outputQueue = new LinkedList<Object>();
		public OutputHandler(ObjectOutputStream oos) {
			this.oos = oos;
		}
		
		public void run() {
			while(true) {
				while(outputQueue.isEmpty()) {
					try {
						oos.writeObject(outputQueue.pop());
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				Thread.yield();
			}
		}
		
		public void addObject(Object o) {
			System.out.println("ENVOIE: " + o.toString());
			outputQueue.addFirst(o);
		}
	}
}